/*
 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
 */
#include <yoc/button.h>
#include "app_main.h"
#include "app_lpm.h"
#include <aos/hal/adc.h>
#include "app_sys.h"
#include "app_bt.h"
#include "breeze_export.h"
#if defined(CONFIG_SMARTLIVING_DEMO) && CONFIG_SMARTLIVING_DEMO
#include <smartliving/exports/iot_export_reset.h>
#include <smartliving/exports/iot_export_awss.h>
#endif

#define TAG "keyusr"

#define MESSAGE_NUM 10
static uint8_t s_q_buffer[sizeof(int) * MESSAGE_NUM];
static aos_queue_t s_queue;

extern int wifi_prov_method;

typedef enum {
    button_id0 = 0,
    button_id1,
    button_id2,
    button_id3,
    button_id4,
    button_id5,
    button_id6,
    button_id7,
    button_id8,
    button_id9,
} button_id_t;

typedef enum {
    inc = 0,
    inc_long,
    pause,
    dec,
    dec_long,
    network,
    power,
    mute,
    reset
} button_event_t;

static void button_evt_cb(uint32_t event_id, const void *param, void *context)
{
    int  button_id = (int)param;
    bool pressed   = false;
    switch (event_id) {
        case EVENT_BUTTON_LONG_PRESSED:
            if (button_id0 == button_id) {
                smtaudio_vol_up(10);
                while ((0 == button_is_pressed(button_id, &pressed)) && pressed) {
                    aos_msleep(1000);
                    smtaudio_vol_up(10);
                }
            } else if (button_id2 == button_id) {
                smtaudio_vol_down(10);
                while ((0 == button_is_pressed(button_id, &pressed)) && pressed) {
                    aos_msleep(1000);
                    smtaudio_vol_down(10);
                }
            } else {
                LOGE(TAG, "unknown button id[%d]", button_id);
            }
            break;
        default:;
    }
}

void button_evt(int event_id, void *priv)
{
    LOGD(TAG, "button(%s)\n", (char *)priv);
    int ret = aos_queue_send(&s_queue, &event_id, sizeof(int));
    if (ret < 0) {
        LOGE(TAG, "queue send failed");
    }
}
static void button_task_thread(void *arg)
{
    int event_id;
    unsigned int len;
     while (1) {
        aos_queue_recv(&s_queue, AOS_WAIT_FOREVER, &event_id, &len);
        switch (event_id) {
            case inc:
                smtaudio_vol_up(10);
                break;

            case inc_long:
                event_publish(EVENT_BUTTON_LONG_PRESSED, (void *)button_id0);
                break;

            case pause:
                if (SMTAUDIO_STATE_PLAYING == smtaudio_get_state()) {
                    smtaudio_pause();
                } else if (SMTAUDIO_STATE_PAUSE == smtaudio_get_state()) {
                    smtaudio_resume();
                }
                break;

            case network:
                smtaudio_stop(MEDIA_ALL);
                //wifi_pair_start();
	            breeze_disconnect_ble();
                breeze_stop_advertising();
                aos_kv_setint("wprov_method", wifi_prov_method);
                printf("method: %d\r\n", wifi_prov_method);
                app_sys_set_boot_reason(BOOT_REASON_WIFI_CONFIG);
                aos_reboot();
                break;

            case dec:
                smtaudio_vol_down(10);
                break;

            case dec_long:
                event_publish(EVENT_BUTTON_LONG_PRESSED, (void *)button_id2);
                break;

            case power:
                LOGD(TAG, "power key shutdown");
                app_lpm_sleep(LPM_POLICY_DEEP_SLEEP, 1);
                aos_msleep(10000);
                break;

            case mute:
                smtaudio_mute();
                break;

            case reset:
                if (0 == aos_kv_reset()) {
#if defined(CONFIG_SMARTLIVING_DEMO) && CONFIG_SMARTLIVING_DEMO
                    iotx_vendor_dev_reset_type_t reset_type = IOTX_VENDOR_DEV_RESET_TYPE_UNBIND_ALL_CLEAR;
                    iotx_sdk_reset(&reset_type);
#endif
                    aos_reboot();
                } else {
                    LOGE(TAG, "kv reset failed!\n");
                }
                break;

            default:
                break;
            }
     }
}
static void button_task_init(void)
{
    aos_task_t task;

    int ret = aos_queue_new(&s_queue, s_q_buffer, MESSAGE_NUM * sizeof(int), sizeof(int));
    aos_check(!ret, EIO);
    aos_task_new_ext(&task, "b-press", button_task_thread, NULL, 4096, AOS_DEFAULT_APP_PRI + 4);
}
void app_button_init(void)
{
    button_init();
    button_task_init();

    button_add_adc(button_id0, "adc0", drv_adc_pin2channel(PIN_ADC_KEY), KEY_ADC_VAL1, KEY_AD_VAL_OFFSET);
    button_add_adc(button_id1, "adc0", drv_adc_pin2channel(PIN_ADC_KEY), KEY_ADC_VAL2, KEY_AD_VAL_OFFSET);
    button_add_adc(button_id2, "adc0", drv_adc_pin2channel(PIN_ADC_KEY), KEY_ADC_VAL3, KEY_AD_VAL_OFFSET);
#if defined(BOARD_CB5654)
    button_add_adc(button_id4, "adc0", drv_adc_pin2channel(PIN_ADC_KEY), KEY_ADC_VAL4, KEY_AD_VAL_OFFSET);
    button_add_adc(button_id5, "adc0", drv_adc_pin2channel(PIN_ADC_KEY), KEY_ADC_VAL5, KEY_AD_VAL_OFFSET);
#elif defined(PIN_ADC_KEY2) 
    button_add_adc(button_id6, "adc0", drv_adc_pin2channel(PIN_ADC_KEY), KEY_ADC_VAL4, KEY_AD_VAL_OFFSET);
    button_add_adc(button_id5, "adc0", drv_adc_pin2channel(PIN_ADC_KEY2), KEY_ADC_VAL5, KEY_AD_VAL_OFFSET);
    button_add_adc(button_id4, "adc0", drv_adc_pin2channel(PIN_ADC_KEY2), KEY_ADC_VAL6, KEY_AD_VAL_OFFSET);
    button_add_adc(button_id7, "adc0", drv_adc_pin2channel(PIN_ADC_KEY2), KEY_ADC_VAL7, KEY_AD_VAL_OFFSET);
    button_add_adc(button_id8, "adc0", drv_adc_pin2channel(PIN_ADC_KEY2), KEY_ADC_VAL8, KEY_AD_VAL_OFFSET);
#endif

#if defined(PIN_TOUCH_PAD)
    button_add_gpio(button_id9, PIN_TOUCH_PAD, LOW_LEVEL);
#endif

    button_evt_t b_tbl[] = {
        {
            .button_id  = button_id0,
            .event_id   = BUTTON_PRESS_UP,
            .press_time = 0,
        }
    };
    button_add_event(inc, b_tbl, sizeof(b_tbl)/sizeof(button_evt_t), button_evt, "inc");

    b_tbl[0].event_id = BUTTON_PRESS_LONG_DOWN;
    b_tbl[0].press_time = 2000;
    button_add_event(inc_long, b_tbl, sizeof(b_tbl)/sizeof(button_evt_t), button_evt, "inc_long");
    
    b_tbl[0].button_id = button_id1;
    b_tbl[0].event_id = BUTTON_PRESS_UP;
    button_add_event(pause, b_tbl, sizeof(b_tbl)/sizeof(button_evt_t), button_evt, "pause");

    b_tbl[0].event_id = BUTTON_PRESS_LONG_DOWN;
    b_tbl[0].press_time = 3000;
    button_add_event(network, b_tbl, sizeof(b_tbl)/sizeof(button_evt_t), button_evt, "network");
    
    b_tbl[0].button_id = button_id2;
    b_tbl[0].event_id = BUTTON_PRESS_UP;
    button_add_event(dec, b_tbl, sizeof(b_tbl)/sizeof(button_evt_t), button_evt, "dec");

    b_tbl[0].event_id = BUTTON_PRESS_LONG_DOWN;
    b_tbl[0].press_time = 2000;
    button_add_event(dec_long, b_tbl, sizeof(b_tbl)/sizeof(button_evt_t), button_evt, "dec_long");

#if defined(SIMULATED_POWER_KEY) && SIMULATED_POWER_KEY
    b_tbl[0].button_id = button_id4;
    b_tbl[0].event_id = BUTTON_PRESS_LONG_DOWN;
    b_tbl[0].press_time = 3000;
    button_add_event(power, b_tbl, sizeof(b_tbl)/sizeof(button_evt_t), button_evt, "power");
#endif

    b_tbl[0].event_id  = BUTTON_PRESS_UP;
    b_tbl[0].button_id = button_id5;
    button_add_event(mute, b_tbl, sizeof(b_tbl)/sizeof(button_evt_t), button_evt, "mute");

    b_tbl[0].event_id  = BUTTON_PRESS_LONG_DOWN;
    b_tbl[0].button_id = button_id5;
    button_add_event(reset, b_tbl, sizeof(b_tbl)/sizeof(button_evt_t), button_evt, "reset");

    event_subscribe(EVENT_BUTTON_LONG_PRESSED, button_evt_cb, NULL);
}